
import { AcGameObject } from "./AcGameObject";//基类
import { Cell } from "./Cell";


export class Bulletsingle extends AcGameObject {
  constructor(tank,gamemap) {
    super();
    // this.cell = new Cell(tank.cell.r+(70-4)/2,tank.cell.c+(70-4)/2);
    this.tank = tank;
    this.direction = tank.direction;

    this.speed = 5;//每秒移动五个格子
    this.status = "move";
    this.gamemap= gamemap;

    
    this.cell = this.get_bullet_rc();

    this.image = new Image();//画图对象

    this.dr = [-1,0,1,0];//canvas坐标下的变化
    this.dc = [0,1,0,-1];

    this.bomb_zheng_count=1;////用于记录子弹爆炸效果的持续时间(暂定10帧)；
  }


  get_bullet_rc(){//获取子弹初始坐标（在炮筒处）
    let r = this.tank.cell.r;
    let c = this.tank.cell.c;
    let width = this.tank.cell.width;//表明宽高都为0.15L
    let height = this.tank.cell.height;

    switch(this.direction){
      case 0:
        return new Cell(r,c+width/2,0.15,0.15);
      case 1:
        return new Cell(r+height/2,c+width,0.15,0.15);
      case 2:
        return new Cell(r+height,c+width/2,0.15,0.15); 
      case 3:
        return new Cell(r+height/2,c,0.15,0.15); 
    }
  }
  set_status(status){
    this.status = status;
  }



  update_move(){//更新每一帧的下一步坐标
    //本来子弹无效的判断逻辑应该写在GameMap里面，像enemy[]一样，死了就从数组删除，此后不再参加判断
    //但是我写到这里，不想再改了，就换了一个思路：
    //1.所有子弹判断都只在本类中，子弹对象即使视觉上被删了（不再渲染），但还是在玩家看不到的情况下继续横冲直撞，还会打墙和坦克
    //2.但是，所有的撞击逻辑都是写在update_move中的，所以只要封了这个函数，也算真正意义上杀死了子弹，为此，特意用direction=-2标识这个状态

    this.cell.c += this.dc[this.direction]*this.speed * this.timedelta / 1000;//这里只是坐标，后面渲染时再乘以格子像素长度
    this.cell.r += this.dr[this.direction]*this.speed * this.timedelta / 1000;//中间运动中的每一帧，只修改cell中的(x,y);

      /*每次到达一个新格子时，就要判断有没有撞到什么东西*****************************************/
      if(this.gamemap.check_boundary_cross(this.cell)){//子弹撞边界了，把子弹销毁
          this.status = "die";//杀死子弹
          this.gamemap.bullets.splice(this.gamemap.bullets.indexOf(this),1);//从子弹列表中删除
          // this.destroy();
      }

      let wall=this.gamemap.check_wall_hit(this.cell);
      if(wall){//撞墙了，把墙和子弹销毁 
        if(wall.kind==="wood"){
          //墙不删除，也不摧毁了，只改状态
          // this.gamemap.walls.splice(this.gamemap.walls.indexOf(wall),1);//光改状态还不行，还要从判断列表中删除
          wall.set_status("die");
          // wall.destroy();//只有墙能在这里销毁，因为墙没有爆炸效果，其他元素要等爆炸完，才能销毁
        }
        this.status="die";//封了update_move这个函数，等效于杀死这个子弹
        this.gamemap.bullets.splice(this.gamemap.bullets.indexOf(this),1);//从子弹列表中删除
        // this.destroy();
      }

      let unknown_ai = this.gamemap.check_ai_hit(this.cell);
      if(unknown_ai && this.tank.kind !== unknown_ai.kind){//子弹撞ai了(但是只能是玩家的子弹才能杀死ai)

          unknown_ai.set_status("die");
          this.status="die";
          this.gamemap.enemys.splice(this.gamemap.enemys.indexOf(unknown_ai),1);//光改状态还不行，还要从判断列表中删除
          this.gamemap.bullets.splice(this.gamemap.bullets.indexOf(this),1);//从子弹列表中删除
          // unknown_ai.destroy();
          // this.destroy();
      }

      let player = this.gamemap.check_player_hit(this.cell);//这里只要调用判断函数，之后的操作因为与子弹来源无关，所以都在外面执行好了
      if(player ){//B玩家可以被除本方ai和自己的所有坦克打死
              //玩家跑得快，可能和自己发射的子弹碰撞，导致死亡

          player.set_status("die");//直接不渲染

          this.status="die";

      }

      let bullet = this.gamemap.check_bullet_hit(this.cell);
      if(bullet && bullet.tank.kind !== this.tank.kind){//撞到了，且是不同阵营，两个子弹都要死
          bullet.set_status("die");
          this.status = "die";
          this.gamemap.bullets.splice(this.gamemap.bullets.indexOf(this),1);//从子弹列表中删除
          this.gamemap.bullets.splice(this.gamemap.bullets.indexOf(bullet),1);//从子弹列表中删除
          // bullet.destroy();
          // this.destroy();
      }

      /**************************************************************************************** */


  }

  bomb_render(){//坦克死后，渲染爆炸效果
    let ctx = this.gamemap.ctx;
    let L = this.gamemap.L;
    this.image.src = require("../images/bomb/bomb.jpg");
    ctx.drawImage(
      this.image,
      this.cell.c*L,//（只对实际坐标画图）转成canvas像素x坐标
      this.cell.r*L,//转成canvas像素y坐标
      0.5*L,
      0.5*L
    );
  }


  start(){//只执行一次
  }

  update(){//每一帧执行一次 ，除了第一次

    //坦克一死，就有爆炸效果，同时bomb_zheng_count逐帧减小，减到0不再展示
    if(this.status==="die" && this.bomb_zheng_count>=0){//爆炸效果只展示30帧
      this.bomb_render();
      this.bomb_zheng_count--;
    }
    if(this.bomb_zheng_count<0)this.destroy();//死了，也爆炸结束了，赶紧销毁吧

    if(this.status==="move")this.update_move();//
    if(this.status!=="die")this.render();//只有当游戏元素没有被销毁时，才会要渲染出来
  }

  render() {//渲染函数，调用draw画出墙
    let ctx = this.gamemap.ctx;
    let L = this.gamemap.L;

    if(this.tank.kind==="ai" || this.tank.kind==="playerB")this.image.src = require("../images/bullet/bullet.jpg");//不知道为什么，这里必须要加require!!我在这卡了一天！！
    else  this.image.src = require("../images/bullet/bullet3.jpg");

    ctx.drawImage(
      this.image,
      (this.cell.c)*L,//（只对实际坐标画图）转成canvas像素x坐标
      (this.cell.r)*L,//转成canvas像素y坐标
      this.cell.width*L,
      this.cell.height*L
    );

  }
}